package com.huayi.datagovernance.utils;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.huayi.datagovernance.common.ResultCode;
import com.huayi.datagovernance.vo.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 封装常用的http请求
 * @author wuch
 * @version 1.0
 * @date 2021/4/13 17:16
 */
//@Component
@Slf4j
public class RestTemplateUtils {

    //手动获取 restTemplate  Bean
    public static RestTemplate restTemplate = SpringUtil.getBean(RestTemplate.class);


    /**
     * get请求（无参数）
     * @author wuch
     * @date 2021/4/14 9:12
     * @param url 请求地址
     * @param responseType 自定义返回类型
     * @return common.parent.system.web.ResponseResult<T>
     */
    public static <T> CommonResult<T> getNoParam(String url, Class<T> responseType){
        T result = null;
        try {
            log.info("远程调用getNoParam....请求地址: {}" , url);
            result = restTemplate.getForObject(url, responseType);
            return CommonResult.success(result);
        } catch (RestClientException e) {
            log.error("远程调用getNoParam失败" , e);
            return CommonResult.failed(ResultCode.REST_FAILED);
        }
    }

    /**
     * get请求（url参数）
     * @author wuch
     * @date 2021/4/14 9:18
     * @param url 请求地址
     * @param responseType 自定义返回类型
     * @param uriVariables url参数
     * @return common.parent.system.web.ResponseResult<T>
     */
    public static <T> CommonResult<T> getWithUrlParam(String url, Class<T> responseType, Map<String, ?> uriVariables) {
        T result = null;
        try {
            if (MapUtil.isEmpty(uriVariables)){
                log.info("远程调用getWithUrlParam....请求地址: {}" , url);
                result = restTemplate.getForObject(url, responseType, new HashMap<>(0));
            }else {
                //拼接Url参数  url?map.key={map.key}&map.key={map.key}
                StrBuilder urlBuilder = StrBuilder.create(url, "?");
                Set<? extends Map.Entry<String, ?>> entries = uriVariables.entrySet();
                for (Map.Entry<String, ?> entry : entries) {
                    Object value = entry.getValue();
                    //空值忽略
                    if (value == null) {
                        continue;
                    }
                    //空字符串忽略
                    if (value instanceof String ){
                        if (StrUtil.isBlank(value.toString())){
                            continue;
                        }
                    }
                    urlBuilder.append(entry.getKey()).append("={").append(entry.getKey()).append("}").append("&");
                }
                String finalUrl = urlBuilder.subString(0, urlBuilder.length() - 1);
                log.info("远程调用getUrlParamAndHeader....请求地址: {}" , finalUrl);
                result = restTemplate.getForObject(url, responseType, uriVariables);
            }
            return CommonResult.success(result);
        } catch (RestClientException e) {
            log.error("远程调用getWithUrlParam失败" , e);
            return CommonResult.failed(ResultCode.REST_FAILED);
        }
    }

    /**
     * get请求（url参数 , 自定义请求头）
     * @author wuch
     * @date 2021/4/14 9:18
     * @param url 请求地址
     * @param headers 请求地址
     * @param responseType 自定义返回类型
     * @param uriVariables url参数
     * @return common.parent.system.web.ResponseResult<org.springframework.http.ResponseEntity<T>>
     */
    public static <T> CommonResult<ResponseEntity<T>> getUrlParamAndHeader(String url, HttpHeaders headers, Class<T> responseType, Map<String, ?> uriVariables) {
        try {
            ResponseEntity<T> result;
            HttpEntity<String>  request = new HttpEntity<>("", headers);
            if (MapUtil.isEmpty(uriVariables)){
                log.info("远程调用getUrlParamAndHeader....请求地址: {}" , url);
                result = restTemplate.exchange(url, HttpMethod.GET, request, responseType, new HashMap<>(0));
            }else {
                //拼接Url参数  url?map.key={map.key}&map.key={map.key}
                StrBuilder urlBuilder = StrBuilder.create(url, "?");
                Set<? extends Map.Entry<String, ?>> entries = uriVariables.entrySet();
                for (Map.Entry<String, ?> entry : entries) {
                    Object value = entry.getValue();
                    //空值忽略
                    if (value == null) {
                        continue;
                    }
                    //空字符串忽略
                    if (value instanceof String ){
                        if (StrUtil.isBlank(value.toString())){
                            continue;
                        }
                    }
                    urlBuilder.append(entry.getKey()).append("={").append(entry.getKey()).append("}").append("&");
                }
                String finalUrl = urlBuilder.subString(0, urlBuilder.length() - 1);
                log.info("远程调用getUrlParamAndHeader....请求地址: {}" , finalUrl);
                result = restTemplate.exchange(finalUrl, HttpMethod.GET, request, responseType, uriVariables);
                if (result.getStatusCodeValue()!=200){
                    return CommonResult.failed(ResultCode.REST_FAILED);
                }
            }
            return CommonResult.success(result);
        } catch (RestClientException e) {
            log.error("远程调用getUrlParamAndHeader失败" , e);
            return CommonResult.failed(ResultCode.REST_FAILED);
        }
    }

    /**
     * post请求-自定义请求头
     * @author wuch
     * @date 2021/4/14 16:43
     * @param url 请求地址
     * @param headers 请求头
     * @param responseType 自定义返回类型
     * @param uriVariables url参数
     * @param json 请求体json
     * @return com.huayi.datagovernance.vo.CommonResult<T>
     */
    public static <T> CommonResult<T> postJson(String url, HttpHeaders headers, Class<T> responseType, Map<String,?> uriVariables, JSONObject json){
        T result = null;
        try {
            //设置body
//            HttpHeaders headers = new HttpHeaders();
//            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
            HttpEntity<String> request = new HttpEntity<>(json.toJSONString(), headers);
            if (MapUtil.isEmpty(uriVariables)){
                log.info("远程调用getUrlParamAndHeader....请求地址: {}" , url);
                result = restTemplate.postForObject(url, request, responseType, new HashMap<>(0));
            }else {
                //封装url参数
                //拼接Url参数  url?map.key={map.key}&map.key={map.key}
                StrBuilder urlBuilder = StrBuilder.create(url, "?");
                Set<? extends Map.Entry<String, ?>> entries = uriVariables.entrySet();
                for (Map.Entry<String, ?> entry : entries) {
                    Object value = entry.getValue();
                    //空值忽略
                    if (value == null) {
                        continue;
                    }
                    //空字符串忽略
                    if (value instanceof String ){
                        if (StrUtil.isBlank(value.toString())){
                            continue;
                        }
                    }
                    urlBuilder.append(entry.getKey()).append("={").append(entry.getKey()).append("}").append("&");
                }
                String finalUrl = urlBuilder.subString(0, urlBuilder.length() - 1);
                log.info("远程调用getUrlParamAndHeader....请求地址: {}" , finalUrl);
                result = restTemplate.postForObject(finalUrl, request, responseType, uriVariables);
            }
            return CommonResult.success(result);
        } catch (RestClientException e) {
            log.error("远程调用getNoParam失败" , e);
            return CommonResult.failed(ResultCode.REST_FAILED);
        }
    }

    /**
     * post请求
     * @author wuch
     * @date 2021/4/14 16:43
     * @param url 请求地址
     * @param responseType 自定义返回类型
     * @param uriVariables url参数
     * @param json 请求体json
     * @return com.huayi.datagovernance.vo.CommonResult<T>
     */
    public static <T> CommonResult<T> postJson(String url, Class<T> responseType, Map<String,?> uriVariables, JSONObject json){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        return postJson(url, headers, responseType, uriVariables, json);
    }

    /**
     * put请求-自定义请求头
     * @param url 请求地址
     * @param headers 请求头
     * @param uriVariables url参数
     * @param json 请求体json
     * @return
     */
    public static CommonResult<String> put(String url, HttpHeaders headers, Map<String,?> uriVariables, JSONObject json){
        try {
//            HttpHeaders headers = new HttpHeaders();
//            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
            HttpEntity<JSONObject> request = new HttpEntity<>(json, headers);
            if (MapUtil.isEmpty(uriVariables)){
                log.info("远程调用put....请求地址: {}" , url);
                restTemplate.put(url, request, new HashMap<>(0));
            }else {
                //封装url参数
                //拼接Url参数  url?map.key={map.key}&map.key={map.key}
                StrBuilder urlBuilder = StrBuilder.create(url, "?");
                Set<? extends Map.Entry<String, ?>> entries = uriVariables.entrySet();
                for (Map.Entry<String, ?> entry : entries) {
                    Object value = entry.getValue();
                    //空值忽略
                    if (value == null) {
                        continue;
                    }
                    //空字符串忽略
                    if (value instanceof String ){
                        if (StrUtil.isBlank(value.toString())){
                            continue;
                        }
                    }
                    urlBuilder.append(entry.getKey()).append("={").append(entry.getKey()).append("}").append("&");
                }
                String finalUrl = urlBuilder.subString(0, urlBuilder.length() - 1);
                log.info("远程调用put....请求地址: {}" , finalUrl);
                restTemplate.put(finalUrl, request, uriVariables);
            }
            return CommonResult.success("远程调用put成功");
        } catch (RestClientException e) {
            log.error("远程调用put失败" , e);
            return CommonResult.failed(ResultCode.REST_FAILED);
        }
    }

    /**
     * put请求
     * @param url 请求地址
     * @param uriVariables url参数
     * @param json 请求体json
     * @return
     */
    public static CommonResult<String> put(String url, Map<String,?> uriVariables, JSONObject json){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        return put(url, headers, uriVariables, json);
    }

    /**
     * delete请求-自定义请求头
     * @param url 请求地址
     * @param headers 请求头
     * @param uriVariables url参数
     * @return
     */
    public static CommonResult<String> delete(String url, HttpHeaders headers, Map<String,?> uriVariables){
        try {
            HttpEntity<String> request = new HttpEntity<>("", headers);
            if (MapUtil.isEmpty(uriVariables)){
                log.info("远程调用delete....请求地址: {}" , url);
               restTemplate.delete(url, request, new HashMap<>(0));
            }else {
                //封装url参数
                //拼接Url参数  url?map.key={map.key}&map.key={map.key}
                StrBuilder urlBuilder = StrBuilder.create(url, "?");
                Set<? extends Map.Entry<String, ?>> entries = uriVariables.entrySet();
                for (Map.Entry<String, ?> entry : entries) {
                    Object value = entry.getValue();
                    //空值忽略
                    if (value == null) {
                        continue;
                    }
                    //空字符串忽略
                    if (value instanceof String ){
                        if (StrUtil.isBlank(value.toString())){
                            continue;
                        }
                    }
                    urlBuilder.append(entry.getKey()).append("={").append(entry.getKey()).append("}").append("&");
                }
                String finalUrl = urlBuilder.subString(0, urlBuilder.length() - 1);
                log.info("远程调用delete....请求地址: {}" , finalUrl);
                restTemplate.delete(url, request, uriVariables);
            }
            return CommonResult.success("远程调用delete成功");
        } catch (RestClientException e) {
            log.error("远程调用delete失败" , e);
            return CommonResult.failed(ResultCode.REST_FAILED);
        }
    }

    /**
     * delete请求-自定义请求头
     * @param url 请求地址
     * @param uriVariables url参数
     * @return
     */
    public static CommonResult<String> delete(String url, Map<String,?> uriVariables){
        HttpHeaders headers = new HttpHeaders();
//        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        return delete(url, headers, uriVariables);
    }
}
